﻿
Imports std

Namespace internalFunctions

    Public Module multilockshare
        Public locks As multilock = Nothing

        Sub New()
            locks = New multilock()
        End Sub

        Friend Delegate Sub lockscall(ByVal key As Int64)

        Friend Function multilockcall(ByVal ctx As context, ByRef output As bare_variable, _
                                      ByVal lockscall As lockscall, _
                                      Optional ByVal para_key As String = "key") As Boolean
            Dim key As Int64
            If ctx.findVariableInt(para_key, key) Then
                lockscall(key)
                output = New bare_variable(typeDefination.bool, True)
                Return True
            Else
                raiseError("expect parameter " + para_key, errorHandle.errorType.user)
                Return False
            End If
        End Function
    End Module

    'parameters, key, int/var, if the int is < multilock.defaultLockCount and >= 0,
    '                          each lock call will have a unique lock object, otherwise, share with some other call.
    'return, bool, success or not
    Public Class multilock_lock
        Inherits internalFunction

        Public Class parameters
            Public Const key As String = "key"
        End Class

        Public Sub New()
            MyBase.New("threads.lock", shared_parameters_mappings.mkey)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Return multilockcall(ctx, output, AddressOf locks.lock(Of Int64))
        End Function
    End Class

    'parameters, key, int/var, if the int is < multilock.defaultLockCount and >= 0,
    '                          each lock call will have a unique lock object, otherwise, share with some other call.
    'return, bool, success or not
    Public Class multilock_release
        Inherits internalFunction

        Public Class parameters
            Public Const key As String = "key"
        End Class

        Public Sub New()
            MyBase.New("threads.unlock", shared_parameters_mappings.mkey)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Return multilockcall(ctx, output, AddressOf locks.release(Of Int64))
        End Function
    End Class

    'parameters, key, int/var
    '            value, template type
    'return, template type, same instance of value if not registered before, otherwise the instance in shared
    Public Class threadshare
        Inherits internalFunction

        Private Shared vars As map(Of Int64, pointer(Of Object)) = Nothing

        Public Class parameters
            Public Const key As String = "key"
            Public Const value As String = "value"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.key, parameters.value)
            vars = New map(Of Int64, pointer(Of Object))()
            cbpnt = New cbpntdef()
            cbv = New cbvdef()
            cbs = New cbsdef()
            cbl = New cbldef()
            cbm = New cbmdef()
        End Sub

        Public Sub New()
            MyBase.New("threads.share", m)
        End Sub

        'object = std.*/pointer
        Private Overloads Shared Function invokeImpl(ByVal i As Object, ByVal key As Int64) As Object
            Dim rtn As Object = Nothing
            Dim it As map(Of Int64, pointer(Of Object)).iterator = Nothing
            SyncLock vars
                it = vars.find(key)
                If it = vars.end() Then
                    vars(key) = New pointer(Of Object)(i)
                    rtn = i
                Else
                    rtn = +((+it).second)
                End If
            End SyncLock

            Return rtn
        End Function

        Private Class cbpntdef
            Inherits pd_t(Of bare_variable)

            Public Overrides Function cb(Of T)(ByRef i As pointer(Of T), ByRef rtn As bare_variable, _
                                               ByVal ET As typeDefination, _
                                               ByVal ParamArray ps() As Object) As Boolean
                rtn = New bare_variable(typeDefination.pointer, ET, _
                                        New elpmis_pointer(Of T)( _
                                            convertor.cast(Of pointer(Of T))( _
                                                invokeImpl(i, paramarray_get(Of Int64)(0, ps)))))
                Return True
            End Function
        End Class
        Private Shared cbpnt As cbpntdef = Nothing

        Private Class cbvdef
            Inherits vd_t(Of bare_variable)

            Public Overrides Function cb(Of T)(ByRef i As vector(Of T), ByRef rtn As bare_variable, _
                                               ByVal et As typeDefination, _
                                               ByVal ParamArray ps() As Object) As Boolean
                rtn = New bare_variable(typeDefination.vector, et, _
                                        New elpmis_vector(Of T)( _
                                            convertor.cast(Of vector(Of T))( _
                                                invokeImpl(i, paramarray_get(Of Int64)(0, ps)))))
                Return True
            End Function
        End Class
        Private Shared cbv As cbvdef = Nothing

        Private Class cbsdef
            Inherits sd_t(Of bare_variable)

            Public Overrides Function cb(Of T As IComparable(Of T))(ByRef i As [set](Of T), _
                                                                    ByRef rtn As bare_variable, _
                                                                    ByVal et As typeDefination, _
                                                                    ByVal ParamArray ps() As Object) As Boolean
                rtn = New bare_variable(typeDefination.set, et, _
                                        New elpmis_set(Of T)( _
                                            convertor.cast(Of [set](Of T))( _
                                                invokeImpl(i, paramarray_get(Of Int64)(0, ps)))))
                Return True
            End Function
        End Class
        Private Shared cbs As cbsdef = Nothing

        Private Class cbldef
            Inherits ld_t(Of bare_variable)

            Public Overrides Function cb(Of T)(ByRef i As list(Of T), ByRef rtn As bare_variable, _
                                               ByVal et As typeDefination, _
                                               ByVal ParamArray ps() As Object) As Boolean
                assert(Not ps Is Nothing AndAlso ps.Length() = 1)
                rtn = New bare_variable(typeDefination.list, et, _
                                        New elpmis_list(Of T)( _
                                            convertor.cast(Of list(Of T))( _
                                                invokeImpl(i, paramarray_get(Of Int64)(0, ps)))))
                Return True
            End Function
        End Class
        Private Shared cbl As cbldef = Nothing

        Private Class cbmdef
            Inherits md_t(Of bare_variable)

            Public Overrides Function cb(Of T As IComparable(Of T), T2)(ByRef i As map(Of T, T2), _
                                                                        ByRef rtn As bare_variable, _
                                                                        ByVal et1 As typeDefination, _
                                                                        ByVal et2 As typeDefination, _
                                                                        ByVal ParamArray ps() As Object) As Boolean
                assert(Not ps Is Nothing AndAlso ps.Length() = 1)
                rtn = New bare_variable(typeDefination.map, et1, et2, _
                                        New pointer(Of map(Of T, T2))( _
                                            convertor.cast(Of map(Of T, T2))( _
                                                invokeImpl(i, paramarray_get(Of Int64)(0, ps)))))
                Return True
            End Function
        End Class
        Private Shared cbm As cbmdef = Nothing

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim key As Int64
            If ctx.findVariableInt(parameters.key, key) Then
                Dim value As bare_variable = Nothing
                value = ctx.findVariable(parameters.value)
                If value Is Nothing Then
                    raiseError("expect int parameter " + parameters.value, errorHandle.errorType.user)
                    Return False
                ElseIf value.variable().isPointer() Then
                    Return value.invoke(output, cbpnt, key)
                ElseIf value.variable().isStdType() Then
                    Return value.invoke(output, cbm, cbv, cbs, cbl, key)
                Else
                    raiseError("expect parameter " + parameters.value + " is pointer or std.*.", _
                               errorHandle.errorType.user)
                    Return False
                End If
            Else
                raiseError("expect parameter " + parameters.key, errorHandle.errorType.user)
                Return False
            End If
        End Function
    End Class

    'parameters, ms, int, the sleep milliseconds
    '            s, int, the sleep seconds
    '            default value is 1 second
    'return, bool, whether the sleep is success or not
    Public Class threadsleep
        Inherits internalFunction

        Public Class parameters
            Public Const ms As String = "ms"
            Public Const s As String = "s"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.ms)
        End Sub

        Public Sub New()
            MyBase.New("sleep", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim i As Int64
            If ctx.findVariableInt(parameters.ms, i) Then
                sleep(i)
            ElseIf ctx.findVariableInt(parameters.s, i) Then
                sleepSeconds(i)
            Else
                sleep()
            End If
            output = New bare_variable(typeDefination.bool, True)
            Return True
        End Function
    End Class
End Namespace